#include "instructions/base/method_invoke_logic.h"
#include "rtda/heap/class.h"
#include <stdexcept>
#include <string>
#include <memory>

namespace jvm {
    namespace instructions {

        void invokeMethod(std::shared_ptr<rtda::Frame> invokerFrame, std::shared_ptr<heap::Method> method) {
            auto thread = invokerFrame->getThread();
            auto newFrame = thread->newFrame(method);
            thread->pushFrame(newFrame);

            int argSlotCount = method->getArgSlotCount();
            if (argSlotCount > 0) {
                for (int i = argSlotCount - 1; i >= 0; i--) {
                    auto slot = invokerFrame->getOperandStack()->popSlot();
                    newFrame->getLocalVars().setSlot(static_cast<uint32_t>(i), slot);
                }
            }

            //// Handle native methods Hack!
            //if (method->isNative()) {
            //    if (method->getName() == "registerNatives") {
            //        thread->popFrame();
            //    }
            //    else {
            //        std::string errorMsg = "native method: " +
            //            method->getClass()->getName() + "." +
            //            method->getName() +
            //            method->getDescriptor();
            //        throw std::runtime_error(errorMsg);
            //    }
            //}
        }

    } // namespace instructions
} // namespace jvm